use serde::Deserialize;
use serde::Serialize;
use ts_rs::TS;
use yata::core::PeriodType;
use yata::core::ValueType;

use super::IndicatorActionWrap;

///
/// Struct to hold the results of The Adx indicator calculations Struct yata::indicators::AverageDirectionalIndex	.
///
///  参见[ADX](https://www.investopedia.com/terms/a/adx.asp)
///
#[derive(Serialize, Deserialize, Default, Debug, TS, Clone)]
#[ts(export)]
pub struct ADX {
    ///2 signals
    /// BUY_ALL when ADX over zone and +DI > -DI,
    /// SELL_ALL when ADX over zone and -DI > +DI.
    /// Otherwise - no signal.
    pub signal0: Option<IndicatorActionWrap>,
    /// Digital signal by difference between +DI and -DI
    pub signal1: Option<IndicatorActionWrap>,

    /// 3 values
    /// ADX
    /// Range in [0.0; 1.0]
    pub adx: ValueType,
    ///+DI
    ///Range in [0.0; 1.0]
    pub di_plus: ValueType,
    ///-DI
    ///Range in [0.0; 1.0]
    pub di_minus: ValueType,
}

/// Configuration for The Adx indicator, Average Directional Index (ADX)
#[derive(Serialize, Deserialize, Debug, TS, Clone, Copy)]
#[ts(export)]
pub struct ADXConfig {
    ///method1: M
    ///Default is RMA(14)
    ///
    ///Period range is in (period1; PeriodType::MAX)
    ///
    pub method1: PeriodType,
    ///method2: M
    ///Default is RMA(14)
    ///
    ///Period range is in (period1; PeriodType::MAX)
    ///
    pub method2: PeriodType,
    ///period1: PeriodType
    ///Default is 1
    ///
    ///Range in [1; min(di_length, adx_smoothing))
    ///
    pub period1: PeriodType,
    ///zone: ValueType
    ///Default is 0.2
    ///
    ///Range in [0.0; 1.0]
    pub zone: ValueType,
}

impl Default for ADXConfig {
    fn default() -> Self {
        Self {
            method1: 14,
            method2: 14,
            period1: 1,
            zone: 0.2,
        }
    }
}
